package com.imooc.reader.management.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.imooc.reader.management.entity.Role;
import com.imooc.reader.management.entity.RoleUser;
import com.imooc.reader.management.entity.User;
import com.imooc.reader.management.mapper.RoleMapper;
import com.imooc.reader.management.mapper.RoleUserMapper;
import com.imooc.reader.management.mapper.UserMapper;
import com.imooc.reader.management.service.UserService;
import com.imooc.reader.management.service.impl.exception.BusinessException;
import jakarta.annotation.Resource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RoleUserMapper roleUserMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = userMapper.selectOne(queryWrapper);
        if (user != null) {
            return user;
        } else {
            throw new UsernameNotFoundException("INCORRECT_USERNAME_OR_PASSWORD");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User createUser(String username, String password, String empName, String deptName) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        List<User> list = userMapper.selectList(wrapper);
        if (list.size() > 0) {
            throw new BusinessException("USERNAME_ALREADY_EXISTS", "用户名已存在");
        }
        // 密码要用BCrypt加密算法加密再存储在数据库中
        password = new BCryptPasswordEncoder().encode(password);
        User user = new User(username, password, 1, empName, deptName);
        userMapper.insert(user);
        QueryWrapper roleWrapper = new QueryWrapper<>();
        roleWrapper.eq("role_code", "USER");
        Role role = roleMapper.selectOne(roleWrapper);
        RoleUser roleUser = new RoleUser(role.getRoleId(), user.getUserId());
        roleUserMapper.insert(roleUser);
        return user;
    }

    @Override
    public IPage<User> selectByRoleCode(IPage page, String roleCode) {
        return userMapper.selectByRoleCode(page, roleCode);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User updateBasicInfo(Integer userId, String empName, String deptName) {
        User user = userMapper.selectById(userId);
        user.setEmpName(empName);
        user.setDeptName(deptName);
        userMapper.updateById(user);
        return user;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User updateStatus(Integer userId) {
        User user = userMapper.selectById(userId);
        user.setStatus(user.getStatus() == 1 ? 0 : 1);
        userMapper.updateById(user);
        return user;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User deleteUser(Integer userId) {
        User user = userMapper.selectById(userId);
        userMapper.deleteById(userId);
        QueryWrapper<RoleUser> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        roleUserMapper.delete(wrapper);
        return user;
    }
}
